<template>
  <div class="course-section">
    <el-card class="box-card">
      <div slot="header" class="clearfix">
        <el-button
          type="primary"
          icon="el-icon-plus"
          @click="handleAddSection">添加阶段</el-button>
      </div>
      <el-tree
        v-loading="isLoading"
        :data="lesson"
        :props="defaultProps"
        draggable
        :allow-drop="handleAllowDrop"
        @node-drop="handleNodeDrop">
        <div class="inner" slot-scope="{ node, data }">
          <!-- 内容设置 -->
          <span>{{ node.label }}</span>
          <!-- 后续按钮结构 -->
          <span v-if="data.sectionName" class="actions">
            <el-button
              size="small"
              @click="handleEditSection(data)"
              >编辑</el-button>
            <el-button size="small" type="primary" @click="hanldeAddLesson(data)">添加课时</el-button>
            <el-button size="small" @click="changeSectionStatus(data)">状态</el-button>
          </span>
          <span v-else class="actions">
            <el-button
              size="small"
              @click="handleEditLesson(data)">编辑</el-button>
            <el-button size="small" type="success"
              @click="$router.push({
                name: 'course-video',
                params: {
                  courseId,
                  lessonId: data.id
                }
              })"
            >上传视频</el-button>
            <el-button size="small"
            @click="changeLessonStatus(data)">状态</el-button>
          </span>
        </div>
      </el-tree>
    </el-card>
    <!-- 对话框 -->
    <el-dialog
      title="章节信息"
      :visible.sync="dialogVisible"
      width="50%">
      <!-- 将添加与编辑功能单独封装到组件 -->
      <section-create-edit
        v-if="dialogVisible"
        :is-edit="isEdit"
        :course-id="courseId"
        :section-id="sectionId"
        @success="handleSuccess"
        @cancel="dialogVisible=false"></section-create-edit>
    </el-dialog>
    <!-- 课时的添加与编辑功能 -->
    <el-dialog
        title="课时基本信息"
        :visible.sync="dialogVisible1"
        width="50%">
      <lesson-create-edit
        v-if="dialogVisible1"
        :is-edit="isEdit"
        :course-id="courseId"
        :section-id="sectionId"
        :lesson-id="lessonId"
        @success="handleSuccess"
        @cancel="dialogVisible1=false"
      ></lesson-create-edit>
    </el-dialog>
    <!-- 状态的变化 -->
    <el-dialog
        title="提示"
        :visible.sync="dialogVisible2"
        width="30%">
      <section-or-lesson-status
        v-if="dialogVisible2"
        :is-section="isSection"
        :section-id="sectionId"
        :lesson-id="lessonId"
        @success="handleSuccess"
        @cancel="dialogVisible2=false"
      ></section-or-lesson-status>
    </el-dialog>
  </div>
</template>

<script>
import { getSectionAndLesson, saveOrUpdateSection, saveOrUpdateLesson } from '@/services/course-section'
import SectionCreateEdit from './components/section-create-edit.vue'
import LessonCreateEdit from './components/lesson-create-edit.vue'
import SectionOrLessonStatus from './components/section-or-lesson-status.vue'

export default {
  name: 'CourseSection',
  components: {
    SectionCreateEdit,
    LessonCreateEdit,
    SectionOrLessonStatus
  },
  props: {
    courseId: {
      type: [Number, String]
    }
  },
  data () {
    return {
      lesson: [],
      defaultProps: {
        children: 'lessonDTOS',
        label (data) {
          // data 是章节或课时的时候，label 的属性名不同，需要检测后使用
          return data.sectionName || data.theme
        }
      },
      isLoading: false,
      // 是否显示对话框
      dialogVisible: false,
      dialogVisible1: false,
      dialogVisible2: false,
      // 是否为编辑
      isEdit: false,
      sectionInfo: null,
      sectionId: '',
      lessonId: '',
      // 是否为 section
      isSection: false
    }
  },
  created () {
    // 加载每个课程对应的全部课程内容
    this.loadAllCourseSection()
  },
  methods: {
    // 改变 section 的状态
    changeSectionStatus (data) {
      this.dialogVisible2 = true
      this.isSection = true
      this.sectionId = data.id
    },
    changeLessonStatus (data) {
      this.dialogVisible2 = true
      this.isSection = false
      this.lessonId = data.id
    },
    hanldeAddLesson (rowData) {
      this.isEdit = false
      this.dialogVisible1 = true
      this.sectionId = rowData.id
    },
    handleEditLesson (rowData) {
      this.isEdit = true
      this.dialogVisible1 = true
      this.sectionId = rowData.sectionId
      this.lessonId = rowData.id
      // this.lessonInfo = rowData
    },
    handleAddSection () {
      this.dialogVisible = true
      this.isEdit = false
    },
    handleEditSection (rowData) {
      this.dialogVisible = true
      this.isEdit = true
      this.sectionId = rowData.id
    },
    handleSuccess () {
      // 隐藏对话框
      this.dialogVisible = false
      this.dialogVisible1 = false
      this.dialogVisible2 = false
      // 刷新列表
      this.loadAllCourseSection()
    },
    async loadAllCourseSection () {
      const { data } = await getSectionAndLesson(this.courseId)
      if (data.code === '000000') {
        this.lesson = data.data
      }
    },
    // 节点拖拽处理函数
    handleAllowDrop (draggingNode, dropNode, type) {
      // - 规则1：只能同级移动，type 不能为'inner'
      // - 规则2：课时不能移动到其他章节中
      return type !== 'inner' && draggingNode.data.sectionId === dropNode.data.sectionId
    },
    // 节点拖拽完毕后的处理函数
    async handleNodeDrop (draggingNode, dropNode, type, event) {
      this.isLoading = true
      try {
        // 由于有很多章节与课时，需要给每个章节与课时都进行最新的排序的请求
        await Promise.all(dropNode.parent.childNodes.map((item, index) => {
          // 判断当前是章节还是课时，再给对应接口发送请求即可
          if (dropNode.data.sectionId) {
            // 这是一个课时接口处理
            return saveOrUpdateLesson({
              id: item.data.id,
              orderNum: index
            })
          } else {
            // 章节接口处理
            return saveOrUpdateSection({
              id: item.data.id,
              orderNum: index
            })
          }
        }))
        this.$message.success('数据更新成功')
      } catch (error) {
        this.$message.error('数据更新失败', error)
      }
      this.isLoading = false
    }
  }
}
</script>

<style lang="scss" scoped>
  .inner {
    flex: 1;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 10px;
    border-bottom: 1px solid #ebeef5;
  }
  ::v-deep .el-tree-node__content {
    height: auto;
  }
</style>
